package cn.edu.nuaa.aadl2.generatorC.template

import cn.edu.nuaa.aadl2.generatorC.utils.Tools
import org.osate.aadl2.AbstractNamedValue
import org.osate.aadl2.BasicPropertyAssociation
import org.osate.aadl2.Classifier
import org.osate.aadl2.DataAccess
import org.osate.aadl2.DataPort
import org.osate.aadl2.DirectionType
import org.osate.aadl2.EnumerationLiteral
import org.osate.aadl2.EventDataPort
import org.osate.aadl2.EventPort
import org.osate.aadl2.Feature
import org.osate.aadl2.Parameter
import org.osate.aadl2.PropertyAssociation
import org.osate.aadl2.PropertyExpression
import org.osate.aadl2.SubprogramAccess
import org.osate.aadl2.SystemImplementation
import org.osate.aadl2.impl.BooleanLiteralImpl
import org.osate.aadl2.impl.ClassifierValueImpl
import org.osate.aadl2.impl.DataTypeImpl
import org.osate.aadl2.impl.IntegerLiteralImpl
import org.osate.aadl2.impl.ListValueImpl
import org.osate.aadl2.impl.NamedValueImpl
import org.osate.aadl2.impl.RecordValueImpl
import org.osate.aadl2.impl.ReferenceValueImpl
import org.osate.aadl2.impl.StringLiteralImpl

import static extension cn.edu.nuaa.aadl2.generatorC.utils.StringUtils.*
import org.osate.aadl2.ProcessSubcomponent

class CoreXml {
	/**
     * 功能：处理每个分区的属性
     * by:qiubao
     */
	static String a
	static BasicPropertyAssociation b
	static PropertyExpression c
	static BasicPropertyAssociation d
	static BasicPropertyAssociation e
	static PropertyExpression f
	static int g =-1
	static int h=0
	static String m
	//创建core.xml文件
	def static createPropertyXml(SystemImplementation system,String system_folder)'''
	«Tools.createFile(system_folder,"core.xml",property2Xml(system).toString())»
		'''
	//总的XML文件生成
	def static property2Xml(SystemImplementation system)'''
    <?xml version="1.0" encoding="UTF-8"?>
    <ARINC_653_Module xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation=".\A653_Part1_revA.xsdClearwater Version 1.1 .xsd" ModuleName="IMA" ModuleVersion="18-Mar-2003">--这一段应该是模型的顶层系统
    	«partitionPort(system)»
    	«partitionMemory(system)»
    	«module_schedule(system)»
    	«partitionCommunicate(system)»
    </ARINC_653_Module >
    '''
    //文件第一段：这一段其实可以分为三个函数处理partition属性的，处理端口属性的，和框架
    def static partitionPort(SystemImplementation system)'''
     	«IF system.allSubcomponents!==null »
		«FOR  subcomponent : system.ownedProcessSubcomponents»
<Partition  «partitionProperty(subcomponent)»>
			«FOR feature:subcomponent.classifier.allFeatures»
				«template(feature)»
			«ENDFOR»
</Partition>
		«ENDFOR»
 	«ENDIF»	
     	'''
     	//文件第一段的分区属性生成：包含分区ID和分区名
     	def static partitionProperty(ProcessSubcomponent subcomponent )'''
     		 			«FOR property:subcomponent.ownedPropertyAssociations»
     		 				«FOR valuelist:property.ownedValues»
     		 				  «var s= valuelist.ownedValue»
«««     		 				  «s.value»
     		 				  «var t =property.property.name»
     		 				  «switch t{
//     		 				  	IntegerLiteralImpl:"PartitionID="+"\"" +s+"\""
//     		 				  	StringLiteralImpl:"PartitionName=" +"\"" +s.value+"\""
								case "Partition_Identifier": "PartitionID="+"\"" +s+"\""case "Partition_Name":"PartitionName=" +"\"" +s.toString.split('"').get(1)+"\""
     		 				  	}»
     		 				«ENDFOR»
     					«ENDFOR»
     	'''
     	//文件第一段的分区端口生成：包含sampling和queueing(有部分代码是原项目代码)
     	def static template(Feature feature){
		switch feature{
			DataPort : '''
				«IF feature.direction.equals(DirectionType.IN)»
				<Sampling_Port PortName="«feature.name.convertNo2Low»" MaxMessageSize="30" Direction="SOURCE"/>
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
				<Sampling_Port PortName="«feature.name.convertNo2Low»" MaxMessageSize="30" Direction="DESTINATION"/>
				«ENDIF»
				«IF feature.direction.equals(DirectionType.IN_OUT)»«ENDIF»
			'''
			EventPort : '''
			Unhandeled EventPort at FeatureTemplate.xtend line 76
			'''
			EventDataPort : '''
				//EventDataPort
				«IF feature.direction.equals(DirectionType.IN)»
				<Queuing PortName="«feature.name.convertNo2Low»" MaxMessageSize="30" Direction="SOURCE"/>
				«ENDIF»
				«IF feature.direction.equals(DirectionType.OUT)»
				<Queuing PortName="«feature.name.convertNo2Low»" MaxMessageSize="30" Direction="DESTINATION"/>
				«ENDIF»
				«IF feature.direction.equals(DirectionType.IN_OUT)»«ENDIF»
			'''
			Parameter : '''
			Unhandeled Patameter at FeatureTemplate.xtend line 87
			'''
			SubprogramAccess:'''
			//feature subprogramaccess 通过引用对应子程序的头文件实现
			extern void «feature.featureClassifier0.toString.clearspace»(paras...);
			'''
			DataAccess:'''
«««			/*此处应该是个全局变量的概念,应该在上层的process 或 system中定义*/
			/* global */
			extern «feature.featureClassifier0.toString.clearspace» «feature.name.convertNo2Low»;
			«FOR property: feature.ownedPropertyAssociations»
				«property.property.fullName» : «property.property.ownedPropertyType»
			«ENDFOR»
			
			'''
		}		
	}
     
	
/**
 * 功能：处理分区的内存分配，分为3个部分：框架，分区属性，内存分配属性
 * by:qiubao
 */
 def static partitionMemory(SystemImplementation system)'''
     «IF system.allSubcomponents!==null »
		«FOR  subcomponent : system.ownedProcessSubcomponents»
<Partition_Memory «partitionProperty(subcomponent)»>
	«partition(subcomponent)»
</Partition_Memory>
			«ENDFOR»
 	«ENDIF»	
     	'''
//分区内存分配属性解析
def static partition(ProcessSubcomponent subcomponent)'''
   «FOR property:subcomponent.ownedPropertyAssociations»
		«FOR valuelist:property.ownedValues»
			«var t = property.property.name»
			«var s= valuelist.ownedValue»
		  	«switch t{
		  	case "Memory_Type":
			null
		  	case "Code_Size":
            '''<Memory_Requirements Type="CODE" SizeBytes="«s.toString.substring(0,s.toString.length()-4)»" Access="READ_ONLY"/>'''
            case "Data_Size":
            '''<Memory_Requirements Type="DATA" SizeBytes="«s.toString.substring(0,s.toString.length()-4)»" Access="READ_WRITE"/>'''
             }»
         «ENDFOR»
    «ENDFOR»
'''
 
/**
 *功能：xml中的分区调度
 *by:qiubao
 */
  	def static module_schedule(SystemImplementation system)'''
	 <Module_Schedule MajorFrameSeconds="«module_schedule_time(system)»">
 		«module_Schedule_part2(system.allPropertyAssociations.get(1))»
	 </Module_Schedule>
	 '''
 	def static module_schedule_time(SystemImplementation system)'''
 	«m =system.allPropertyAssociations.get(0).ownedValues.get(0).ownedValue.toString.substring(0,3)»
 	'''
	
 def static module_Schedule_part2(PropertyAssociation property) '''
		«FOR value : property.ownedValues»
			«var ownedValue=value.ownedValue»
			«switch ownedValue{
				NamedValueImpl:
					'''«ownedValue.namedValue.parseNamedValue»'''
				StringLiteralImpl:
					'''«ownedValue.value+"(features...);"»'''
				ListValueImpl:
					'''«ownedValue.parseListValue»'''
				default:
					'''«ownedValue.toString»'''
			}
			»
		«ENDFOR»
	'''
	//测试，为什么把两个分区分开？？？？
	def static module_schedule1(SystemImplementation system)'''
	 «IF system.allSubcomponents!==null »
	 		«FOR  sysProperty : system.allPropertyAssociations»
				«var s=sysProperty.property.name»
				«var t =sysProperty.ownedValues»
				«switch s{
					case "Module_Major_Frame": '''<Module_Schedule MajorFrameSeconds="«t.get(0).ownedValue.toString.substring(0,3)»">'''
					case "Module_Schedule" :moduleSchedule(sysProperty)
				}»
	 		«ENDFOR»
	  	«ENDIF»	
	 '''
	def static moduleSchedule(PropertyAssociation pa)'''
		«FOR list2:pa.ownedValues»		--pa的属性
			«var list3=list2.ownedValue»--这里拿到的是Module_Schedule两个元素
				«FOR list4:list3.ownedElements»	
					«FOR value:list4.ownedElements»	--这里应该拿每项里的3个元素
	«««				«var value=list3.ownedValues»
	«««				«var name=list3.property.name»
					«println(value.toString)»
	«««				«println(name)»
					«ENDFOR»
				«ENDFOR»
		«ENDFOR»
		<Partition_Schedule PartitionName="partition1" PeriodSeconds="«m»" PeriodDurationSeconds="«»">
		   	    <Window_Schedule WindowIdentifier="101" WindowStartSeconds="0.0" WindowDurationSeconds="0.040"/>
		  	</Partition_Schedule>
	'''
/**
 * 功能：分区间通信channel：下面的分区间通信，以后要考虑subprogram的
 * by:邱宝
 */
 def static partitionCommunicate(SystemImplementation system)'''

   	«IF system.allConnections!==null»
   		«FOR connection:system.ownedConnections»
   			«FOR connectProperty: connection.ownedPropertyAssociations»
   				«IF connectProperty!=null»
				<Channel ChannelID="«connectProperty.ownedValues.get(0).ownedValue»" ChannelName="«connection.name» ">
				   <Source>
				      <Partition PartitionName="«connection.source.context.name»" PortName="«connection.source.connectionEnd.name» "/>
				   </Source>
				   <Destination>
				      <Partition PartitionName="«connection.destination.context.name» " PortName="«connection.destination.connectionEnd.name» "/>
				   </Destination>
   				«ENDIF»
						<Destination>
						   <Partition PartitionName="«connection.destination.context.name» " PortName="«connection.destination.connectionEnd.name» "/>
						</Destination>
	</Channel>
   			«ENDFOR»	
   		«ENDFOR»
   	«ENDIF»
   
 '''

 def static parseNamedValue(AbstractNamedValue  value) {
		switch value{
			EnumerationLiteral:
				 return value.name
			RecordValueImpl:
				return value.toString
			default:
				return value.class.name
		}
	}
 
 /**
	 * 当前针对StringLiteralImpl的处理,在每个property的property.ownedValues的for循环中不断解析 ListValueImpl
	 * */
	def static parseListValue(ListValueImpl value)'''
		«FOR expression:value.ownedListElements»
			«switch expression{
						StringLiteralImpl:
							'''«expression.value»''' 
						NamedValueImpl:
							'''«expression.namedValue.parseNamedValue»'''
						ClassifierValueImpl:
							'''«expression.classifier.parseClassifier»'''
						IntegerLiteralImpl:
							'''«expression»'''
						RecordValueImpl :
							 '''«recordValueImpl(expression)»'''
						default:
							'''«expression.toString»'''
				}»
		«ENDFOR»
	'''
	def static recordValueImpl(RecordValueImpl recordlist){
		for(record:recordlist.ownedFieldValues) {
			switch record.ownedValue{
		
						StringLiteralImpl:
						 record.value
						NamedValueImpl:
						 record.ownedValue
						ClassifierValueImpl:
						 d = record
						IntegerLiteralImpl:
						 c = record.value
						RecordValueImpl :
						 e = record
					    ReferenceValueImpl:
					     a = record.property.name
					    BooleanLiteralImpl:
					     record.value
						default:
						 record.toString
							}
		}
			g = g+1
			recordValueImpl1(recordlist)
			
	}
		 //问题出在这里
	def static recordValueImpl1(RecordValueImpl recordlist)'''
		<Partition_Schedule PartitionName="«a»" PeriodSeconds="«m»" PeriodDurationSeconds="«c.toString.substring(0,3)»">
			<Window_Schedule WindowIdentifier="«101+g»" WindowStartSeconds="«a»" WindowDurationSeconds="«c.toString.substring(0,3)»"/>
		</Partition_Schedule>
	'''
	
	 def static parseClassifier(Classifier classifier){
			var clazz=classifier
			try {
				var type=(clazz as DataTypeImpl).name
				return type
			} catch (Exception exception) {
				return "Classifier can't be cast to DataTypeImpl . fdafds in PropertyTemplate.xtend !! \n"
			}
		}
 	//这个是原来804项目处理features的方法，暂时留着
     	def static getFeatureClassifier0(Feature feature){
		if(feature.classifier!==null){
			var f=feature.classifier.name.convertNo2Low
			switch f{
				case "Integer":
					return "int"
				default:
					return f
			}
		}else{
			return feature.name +"'s classifier is null. error in FeatureTemplate line 58"
		}
	}
}